package com.dh.blog.sitemap;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.ewei.web.common.exception.MessageRuntimeException;

public class SitemapImpl implements Sitemap{
	private static XPath xpath;
	static{
		XPathFactory factory = XPathFactory.newInstance();
		xpath = factory.newXPath();
	}
	private static Sitemap sitemap = null;
	private SitemapImpl(){
	}
	public static Sitemap getInstance(){
		if(null == sitemap){
			synchronized(SitemapImpl.class){
				if(null == sitemap){
					sitemap = new SitemapImpl();
				}
			}
		}
		return sitemap;
	}
	private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
	private org.w3c.dom.Document doc = null;
	@Override
	public void addOrUpdateURL(SitemapURL url) {
		lock.writeLock().lock();
		try{
			if(null != doc){
				try {
					Node node = (Node) xpath.evaluate("//loc[text()='"+url.getLoc()+"']/parent::url", this.doc,XPathConstants.NODE);
					if(null != node){
						
					}else{
						node = doc.createElement("url");
						
						((Node)xpath.evaluate("//urls", this.doc,XPathConstants.NODE)).appendChild(node);
					}
					
				} catch (XPathExpressionException e) {
					throw new RuntimeException(e);
				}
			}
		}finally{
			lock.writeLock().unlock();
		}
	}

	@Override
	public void removeURL(String loc) {
		lock.writeLock().lock();
		try{
			if(null != doc){
				
			}
		}finally{
			lock.writeLock().unlock();
		}
	}
	@Override
	public void building() {
		lock.writeLock().lock();
		try{
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			InputStream in = getInput(PATH_NAME);
			try {
				InputSource source = new InputSource(in);
				source.setEncoding("UTF-8");
				this.doc = builder.parse(source);
			} catch (SAXException e) {
				throw new MessageRuntimeException(e);
			} catch (IOException e) {
				throw new MessageRuntimeException(e);
			}
			}catch(ParserConfigurationException ex){
				throw new MessageRuntimeException(ex);
		}finally{
			lock.writeLock().unlock();
		}
	}
	@Override
	public void finish() {
		lock.writeLock().lock();
		try{
			
		}finally{
			lock.writeLock().unlock();
		}
	}
	private InputStream getInput(String path){
		String resolve = "";
		if(path.startsWith("classpath:")){
			resolve = path.substring(path.indexOf(":")+1);
			resolve = this.getClass().getClassLoader()
					.getResource(resolve).getPath();
			System.out.println("true_path:"+resolve);
		}else{
			resolve = path;
		}
		try {
			return new FileInputStream(resolve);
		} catch (FileNotFoundException e) {
			throw new RuntimeException(e);
		}
	}
	private void mappedNode(Object obj,Node node){
		Class clz = obj.getClass();
		Field[] fields = clz.getFields();
		for(int i = 0;i<fields.length;i++){
//			fields[i].getAnnotation(")
		}
	}
}
